package org.mf.security.manager;

import org.mf.dao.UserDAO;
import org.mf.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Service;
import org.springframework.validation.ValidationUtils;

import com.google.inject.persist.Transactional;

@Service("customAuthenticationManager")
@Transactional
public class CustomAuthenticationManager implements AuthenticationManager {
	// password + "{" + salt.toString() + "}";
	private UserDAO userDao;
	private Md5PasswordEncoder passwordEncoder;

	@Autowired
	public CustomAuthenticationManager(UserDAO userDao,
			Md5PasswordEncoder passwordEncoder) {
		this.userDao = userDao;
		this.passwordEncoder = passwordEncoder;
	}

	public Authentication authenticate(Authentication auth)
			throws AuthenticationException {
		User user = null;
		if (auth.getName() == null || "".equals(auth.getName())) {
			throw new BadCredentialsException("Username is required");
		}
		try {
			user = userDao.getUserByUsername(auth.getName());
		} catch (Exception e) {
			throw new BadCredentialsException("User does not exist");
		}

		if (passwordEncoder.isPasswordValid(user.getPassword(),
				(String) auth.getCredentials(), user.getSalt()) == false) {
			throw new BadCredentialsException("Wrong password!");
		}

		// Here's the main logic of this custom authentication manager
		// Username and password must be the same to authenticate
		if (auth.getName().equals(auth.getCredentials()) == true) {
			throw new BadCredentialsException(
					"Entered username and password are the same!");
		} else {
			return new UsernamePasswordAuthenticationToken(auth.getName(),
					auth.getCredentials(), user.getGrantedAuthorities());
		}
	}
}
